<!--
@function: 这是一个可以插入行的表格组件
@author:ZY
@description:
1.结构：
  该组件包含一个表格以及三个控制按钮
2.设置：
  tableData:表格数据
  columns:  表格列，是一个数组，数组元素所包括的属性：
            字段代号prop:String，
            汉字名称label:String,
            宽度width:Number
            对齐align:String
            标题对齐headerAlign:String
            渲染类型type：String
                当type是不同的值时，需要传入一些可选项配合渲染，
                type=number:
                    最小值min：Number
                    最大值max：Number
                type=date:
                    日期渲染类型dateType：String，默认为date，详见el-date-picker说明
                    日期渲染类型dateFormat：String，默认为yyyy-MM-dd，详见el-date-picker说明
                    日期的值格式是timestamp
                type=select:
                    值的键名valueKey:String,默认值为value
                    标签的键名labelKey:String,默认值为label
                    下拉选择元素options：Array,一个对象的数组
                        汉字名称label:String，
                        选项值value：int/String/Boolean
                    相关列aboutColumns：Object,表格中的某些列的值可能会根据下拉选择的变化而变化，
                        {
                          "table-col-prop":"select-option-key",
                          "table-col-prop":"select-option-key",
                        }
                        键是表格列的prop，值是选中
                type=checkboxGroup:
                    复选框配置checkboxs:Array,
                        复选框标签label:String
  rowItem:  表格行，内容是tableData中的一个元素，用于添加行
  showRowNumber:Boolean 显示行号列 
  multiSelection:Boolean 显示多选的复选框列
  height:Number 表格主体高度
  indexColumn:
  ishealthConcerns:
  buttonPosition:String控制操作按钮的位置
  addBtnText: String按钮文字
  insBtnText: String按钮文字
  delBtnText: String按钮文字
  showAddBtn: Boolean按钮显示控制，默认true
  showInsBtn: Boolean按钮显示控制，默认true
  showDelBtn: Boolean按钮显示控制，默认true
  addBtnClsType：String按钮样式类型，默认success
  insBtnClsType：String按钮样式类型，默认success
  delBtnClsType：String按钮样式类型，默认success
3.行为： 
  通过设置表格列的type，可以把表格渲染成各种各样的表单组件
  点击添加行会在表格最下方添加一行表格，点击插入列后会在第一条被选中行的上方添加一行表格，点击删除行会将所有选中的行删除

@modify:ljr 2018-6-24
修改内容：1.新增了序号模板列 <el-table-column v-if="col.type=='myIndex'" type="index" :label="col.label" :width="col.width" :index="indexValue"></el-table-column>
2.新增了模板checkbox（el-checkbox-group）
@modify:胡杨升 2018-9-12
修改内容：1.添加了对隐藏列的响应，也就是列中hidden属性的响应
         2.添加了number列，也就是type=number，并且需要指定min和max作为取值范围
         3.日期列，添加了对属性dateFormat和dateType的响应，前者指定日期格式，后者指定日期框交互方式，默认分别为yyyy-MM-dd和date
         4.添加了按钮位置的控制属性，默认是在下方，可以通过buttonPosition属性来调整位置，目前有这几个可选值:bottomCenter,topLeft,bottomLeft
         5.添加了对按钮文字的修改和按钮的显示控制，通过属性addText，insText，delText来修改文字，通过属性showAddBtn,showInsBtn,showDelBtn来控制显示


 -->
<template>
  <div class="dynamic-table">
    <el-header v-if="buttonPosition == 'topLeft'" height="40px" class="toolbar">
      <el-row type="flex" justify="start" class="button-box">
        <el-button v-if="showAddBtn" :type="addBtnClsType" size="mini" icon="el-icon-plus" @click="addRow">{{addBtnText}}</el-button>
        <el-button v-if="showInsBtn" :type="insBtnClsType" size="mini" icon="el-icon-plus" @click="insertRow">{{insBtnText}}</el-button>
        <el-button v-if="showDelBtn" :type="delBtnClsType" size="mini" icon="el-icon-minus" @click="delRow">{{delBtnText}}</el-button>
      </el-row>
    </el-header>
    <el-table :data="tableData" :height="height" style="width: 100%" size="medium"
    @selection-change="tableSelectionChange($event)" border>
      <el-table-column v-if="multiSelection" type="selection" width="50"></el-table-column>
     <el-table-column v-if="showRowNumber" type="index" width="50"></el-table-column>
      <template v-for="(col, colIdx) in this.columns">
        <template v-if="!col.hidden">
          <!-- ljr加 -->
          <el-table-column v-if="col.type=='myIndex'" :key="colIdx" type="index" :label="col.label" :width="col.width?col.width:60" :index="indexValue">
          </el-table-column>
          <el-table-column v-else :key="colIdx" :prop="col.prop" :label="col.label" :width="col.width"
          :align="col.align?col.align:'left'" :header-align="col.headerAlign?col.headerAlign:'center'">
            <template slot-scope="scope">
              <!-- 文本输入 -->
              <el-input style="width:100%;" v-if="col.type=='input'" size="mini" 
              v-model="scope.row[col.prop]" :readonly="col.readonly"></el-input>
              <!-- 文本域输入 -->
              <el-input style="width:100%;" v-else-if="col.type=='textarea'" size="mini" type="textarea" 
              v-model="scope.row[col.prop]" :readonly="col.readonly"></el-input>
              <!-- 日期输入 -->
              <el-date-picker style="width:100%;" v-else-if="col.type=='date'" size="mini" type="date" 
              :format="scope.row[col.dateFormat]?scope.row[col.dateFormat]:'yyyy年MM月dd日'" 
              value-format="timestamp" v-model="scope.row[col.prop]" :readonly="col.readonly"></el-date-picker>
              <!-- 选择 -->
              <el-select v-else-if="col.type=='select'" size="mini" v-model="scope.row[col.prop]" :filterable="col.filterable"
              @change="selectionChange($event, col.valueKey, col.aboutColumns, col.options, scope.$index)">
                <el-option v-for="(item,idx) in col.options" :key="idx"
                :label="item[col.labelKey]" :value="item[col.valueKey]">
                  <span style="float: left">{{ item[col.labelKey] }}</span>
                  <span style="float: right; color: #8492a6; font-size: 13px">{{item[col.valueKey]}}</span>
                </el-option>
              </el-select>
              <!-- ljr加，复选框 -->
              <el-checkbox-group style="width:100%;" v-model="checkboxArr" @change="checkboxValueChange" v-else-if="col.type=='checkboxGroup'">
                <template v-for="(checkbox,idx) in col.checkboxs">
                  <el-checkbox :key="idx" :label="checkbox.label">&nbsp;</el-checkbox>
                </template>
              </el-checkbox-group>
              <!-- hys加，数字输入 -->
              <el-input-number style="width: 100%" v-else-if="col.type==='number'" size="mini" 
              v-model="scope.row[col.prop]" :readonly="col.readonly" :min="col.min" :max="col.max"></el-input-number>
              <!-- 不渲染为组件的列，显示为纯文本 -->
              <span v-else v-text="scope.row[col.prop]"></span>
            </template>
          </el-table-column>
        </template>
      </template>
    </el-table>
    <el-footer v-if="buttonPosition == 'bottomLeft'" height="40px" class="toolbar">
      <el-row type="flex" justify="start" class="button-box">
        <el-button v-if="showAddBtn" :type="addBtnClsType" size="mini" icon="el-icon-plus" @click="addRow">{{addBtnText}}</el-button>
        <el-button v-if="showInsBtn" :type="insBtnClsType" size="mini" icon="el-icon-plus" @click="insertRow">{{insBtnText}}</el-button>
        <el-button v-if="showDelBtn" :type="delBtnClsType" size="mini" icon="el-icon-minus" @click="delRow">{{delBtnText}}</el-button>
      </el-row>
    </el-footer>
    <div v-if="buttonPosition == 'bottomCenter'" class="button-box">
      <el-button v-if="showAddBtn" :type="addBtnClsType" icon="el-icon-plus" @click="addRow">添加行</el-button>
      <el-button v-if="showInsBtn" :type="insBtnClsType" icon="el-icon-plus" @click="insertRow">插入行</el-button>
      <el-button v-if="showDelBtn" :type="delBtnClsType" icon="el-icon-minus" @click="delRow">删除行</el-button>
    </div>
  </div>
</template>

<script>
import {cloneObj} from "../../utils/utils.js";

export default {
  name: "dynamic-table",
  props: {
    showRowNumber:{// 显示行号
      type:Boolean,
      default:false
    } , 
    multiSelection: {// 显示复选框
      type: Boolean,
      default: true
    },
    columns: { // 表格列
      type: Array,
      default: () => {
        return [];
      }
    },
    height: { // 表格主体高度
      type: Number,
      default: () => {
        return null;
      }
    },
    rowItem: {// 表格行
      type: Object,
      default: () => {
        return {};
      }
    },
    tableData:{// 表格数据
      type:Array,
      default:()=>{
        return [];
      }
    },
    indexColumn:{
      type:String,
      default:()=>{
        return "";
      }
    },
    buttonPosition:{// 控制操作按钮的位置
      type:String,
      default:"bottomCenter"
    },
    addBtnText:{// 按钮文字
      type:String,
      default:"添加行"
    },
    insBtnText:{// 按钮文字
      type:String,
      default:"插入行"
    },
    delBtnText:{// 按钮文字
      type:String,
      default:"删除行"
    },
    showAddBtn:{// 按钮显示控制
      type:Boolean,
      default:true
    },
    showInsBtn:{// 按钮显示控制
      type:Boolean,
      default:true
    },
    showDelBtn:{// 按钮显示控制
      type:Boolean,
      default:true
    },
    addBtnClsType:{// 按钮样式类型
      type:String,
      default:"success"
    },
    insBtnClsType:{// 按钮样式类型
      type:String,
      default:"success"
    },
    delBtnClsType:{// 按钮样式类型
      type:String,
      default:"success"
    }
  },
  methods: {
    addRow () {// 添加行
      this.tableData.splice(this.tableData.length,0,cloneObj(this.rowItem));
      this.$emit("add-row");
    },
    insertRow () {// 插入行
      if(this.index == -1){
        this.$message.warning({message:"请选择要插入的位置"});
        return;
      }
      this.tableData.splice(this.index,0,cloneObj(this.rowItem));
      this.$emit("insert-row");
    },
    delRow () {// 删除行
      var me = this;
      if(me.index == -1){
        this.$message.warning({message:"请选择要删除的行"});
        return;
      }

      this.$emit("delete-row", me.tableSelections);// 2018年10月17日 胡杨升 这样可以在外部先进行处理，然后再去掉

      me.tableSelections.forEach((item) => {
        me.tableData.splice(me.tableData.indexOf(item),1);
      })
      // this.$emit("delete-row", me.tableSelections);
    },
    tableSelectionChange (selections) {// 表格选中发生改变事件
      var me = this;
      // console.log(me.tableData);
      var index = -1;
      selections.forEach((item) =>{
        var i = me.tableData.indexOf(item);
        if(index == -1 || i<index){
          index = i;
        }
      });
      me.index = index;
      me.tableSelections = selections;
    },
    selectionChange (value, valueKey, aboutColumns, options, index) {// 下拉选择框选择改变事件
      var me = this;
      if(!(aboutColumns instanceof Object)){
        return;
      }
      // 首先找到对应行
      var selected;
      options.forEach(function(op){
        if(value == op[valueKey]){
          selected = op;
          return;
        }
      });
      //根据相关列的对应，填充对应数据
      for(let key in aboutColumns){
        let val = aboutColumns[key];
        me.tableData[index][key] = selected[val];
      }

      me.$emit("inner-select", value, valueKey, selected, aboutColumns, options, index);
 
    },
    getTableData () {
      this.$emit("get-tableData", this.tableData);
    },
    checkboxValueChange(){//ljr加
      if(this.checkboxArr.length > 0){
        this.checkboxArr.splice(0,this.checkboxArr.length-1);
      }
      this.$emit("value-change",this.checkboxArr);
    },
    indexValue(index){//ljr加
      this.tableData[index][this.indexColumn] = index+1;
      return index+1;
    }
  },
  data () {
    return {
      // rowItem:{//
      //   "jcdx": "",
      //   "jcmx": "",
      //   "jcnr": "",
      //   "dw": "",
      //   "sfyc": "",
      //   "ckfw": "",
      //   "jcsj": new Date(),
      // },
      tableSelections: [],// 表格选中的数据
      index:-1,// 选中的第行表格位置，用于插入行
      checkboxArr:[]//ljr加
    }
  },
  created: function() {
    var me = this;
    if(me.tableData.length==0){// 如果传入的表格数据为空，则向表格数据中添加一行空的数据
      var row = cloneObj(me.rowItem);
      me.tableData.splice(0,0,row);
    }
  }
}
</script>

<style lang="scss">
.dynamic-table{
  .button-box{
    margin-top: 20px;
  }

  .el-checkbox + .el-checkbox{
    margin-left: 10px; 
  }
  .el-table .cell {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal;
    word-break: break-all;
    line-height: 23px;
    padding-left: 20px;
    padding-right: 10px;
    text-align:center;
  }
}
</style>
